package com.tevintao.marketingsystem.provider;

import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

import com.tevintao.marketingsystem.log.LogManager;
import com.tevintao.marketingsystem.task.WxUiViewConfig;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;


public class ContactsManager {

    public static final String SQL_NAME = "/mnt/sdcard/ms/contacts.sqlite";//数据库名称。
    public static final String MAIN_DATA_TABLE_NAME = "contacts";//表名。

    public static String createContactsDb = "create table if not exists " + MAIN_DATA_TABLE_NAME + "("
            + "account varchar(30), "
            + "sort_key varchar(30), "
            + "photo_uri varchar(30) , "
            + "status_label varchar(30), "
            + "status_ts varchar(30), "
            + "status_res_package varchar(30), "
            + "sim_id INTEGER DEFAULT -1, "
            + "name_verified INTEGER DEFAULT 0, "
            + "display_name varchar(30), "
            + "indicate_phone_or_sim_contact INTEGER DEFAULT -1, "
            + "last_time_used varchar(30), "
            + "send_to_voicemail_sip INTEGER DEFAULT 0, "
            + "mimetype varchar(30), "
            + "phonebook_label_alt varchar(30), "
            + "data6 varchar(30), "
            + "version INTEGER, "
            + "photo_id varchar(30), "
            + "data3 varchar(30), "
            + "custom_ringtone varchar(30), "
            + "times_contacted INTEGER DEFAULT 0, "
            + "account_type_and_data_set varchar(30), "
            + "dirty INTEGER DEFAULT 1, "
            + "data7 varchar(30), "
            + "data15 varchar(30), "
            + "raw_contact_is_user_profile INTEGER DEFAULT 0, "
            + "data_set varchar(30), "
            + "phonebook_label varchar(30), "
            + "data10 varchar(30), "
            + "res_package varchar(30), "
            + "account_type varchar(30), "
            + "data11 varchar(30), "
            + "display_name_alt varchar(30), "
            + "lookup varchar(30), "
            + "phonetic_name varchar(30), "
            + "last_time_contacted INTEGER DEFAULT 0, "
            + "contact_last_updated_timestamp INTEGER, "
            + "data13 varchar(30), "
            + "in_visible_group INTEGER DEFAULT 1, "
            + "chat_capability varchar(30), "
            + "data9 varchar(30), "
            + "data_sync1 varchar(30), "
            + "sort_key_alt varchar(30), "
            + "contact_presence varchar(30), "
            + "data_version INTEGER DEFAULT 0, "
            + "phonetic_name_style INTEGER DEFAULT 0, "
            + "name_raw_contact_id INTEGER DEFAULT 1, "
            + "raw_contact_id INTEGER DEFAULT -1, "
            + "index_in_sim INTEGER DEFAULT -1, "
            + "send_to_voicemail INTEGER DEFAULT 0, "
            + "data4 varchar(30), "
            + "data12 varchar(30), "
            + "contact_status varchar(30), "
            + "contact_status_label varchar(30), "
            + "pinned INTEGER DEFAULT 0, "
            + "timestamp varchar(30), "
            + "status_icon varchar(30), "
            + "status varchar(30), "
            + "data1 varchar(30) UNIQUE, "
            + "phonebook_bucket INTEGER, "
            + "data_sync2 varchar(30), "
            + "contact_status_res_package varchar(30), "
            + "in_default_directory INTEGER DEFAULT 1, "
            + "_id INTEGER DEFAULT 1, "
            + "is_super_primary INTEGER DEFAULT 0, "
            + "data5 varchar(30), "
            + "contact_id INTEGER DEFAULT 1, "
            + "send_to_voicemail_vt INTEGER DEFAULT 0, "
            + "data8 varchar(30), "
            + "is_primary vINTEGER DEFAULT 0, "
            + "data_sync4 varchar(30), "
            + "is_sdn_contact INTEGER DEFAULT 0, "
            + "is_additional_number INTEGER DEFAULT 0, "
            + "has_phone_number INTEGER DEFAULT 1, "
            + "display_name_source INTEGER, "
            + "photo_file_id varchar(30), "
            + "data_sync3 varchar(30), "
            + "data14 varchar(30), "
            + "contact_status_ts varchar(30), "
            + "phonebook_bucket_alt INTEGER, "
            + "mode varchar(30), "
            + "data2 INTEGER, "
            + "group_sourceid varchar(30), "
            + "starred INTEGER DEFAULT 0, "
            + "photo_thumb_uri varchar(30), "
            + "times_used varchar(30), "
            + "contact_status_icon varchar(30), "
            + "contact_chat_capability varchar(30), "
            + "account_name varchar(30), "
            + "sourceid varchar(30)); ";


    private static ContactsManager ourInstance = new ContactsManager();

    public static ContactsManager getInstance() {
        return ourInstance;
    }

    private SQLiteDatabase mDatabase;

    private ContactsManager() {
    }

    public SQLiteDatabase getDb() {
        if (null == mDatabase) {
            File dbFile = new File(SQL_NAME);
            if (dbFile.exists()) {
                mDatabase = SQLiteDatabase.openOrCreateDatabase(dbFile, null);
            } else if (!dbFile.exists()) {
                mDatabase = SQLiteDatabase.openOrCreateDatabase(dbFile, null);
                mDatabase.execSQL(createContactsDb);
            }
        }
        return mDatabase;
    }

    private Random mRandom = new Random();

    public Cursor queryAll(String account) {
        SQLiteDatabase db = getDb();
        return db.query(MAIN_DATA_TABLE_NAME, null, "account=?", new String[]{account}, null, null, null);
    }

    public boolean insertContacts(String account, String name, String phone) {
        SQLiteDatabase db = getDb();
        int count = db.query(MAIN_DATA_TABLE_NAME, null, "account=?", new String[]{account}, null, null, null).getCount() + 1;
        LogManager.getInstance().logInfo("insertContacts count = " + count);
        int randomDate = mRandom.nextInt(24);
        long pastMill = randomDate * 60 * 60 * 1000;
        long phoneTime = System.currentTimeMillis() - pastMill;
        ContentValues cv = new ContentValues();
        cv.put("account", account);
        cv.put("display_name", name);
        cv.put("display_name_alt", name);
        cv.put("data1", phone);
        cv.put("data4", "+86" + phone);
        cv.put("contact_last_updated_timestamp", phoneTime);

        cv.put("version", count);
        cv.put("name_raw_contact_id", count);
        cv.put("raw_contact_id", count);
        cv.put("contact_id", count);
        cv.put("data2", count);

        cv.put("index_in_sim", -1);
        return db.insert(MAIN_DATA_TABLE_NAME, null, cv) > 0;
    }

    public boolean deletePhone(String name, String phone) {
        SQLiteDatabase db = getDb();
        return db.delete(MAIN_DATA_TABLE_NAME, "display_name=? and data1=?", new String[]{name, phone}) > 0;
    }

    public boolean clearDb() {
        SQLiteDatabase db = getDb();
        return db.delete(MAIN_DATA_TABLE_NAME, null, null) > 0;
    }

    private static Random random = new Random();
    public static final int max_contacts_num = 100;
    public static final int delete_contacts_num = 20;

    private void deletePhone(String account) {
        HashMap<String, String> mDeleteMap = new HashMap<>();

        Cursor cursor = queryAll(account);
        if (cursor.getCount() > max_contacts_num) {
            LogManager.getInstance().logError("通讯录数量过多");
            int num = random.nextInt(max_contacts_num - delete_contacts_num);
            cursor.move(num);
            int deleteCount = 0;
            while (cursor.moveToNext() && deleteCount < delete_contacts_num) {
                String name = cursor.getString(cursor.getColumnIndex("display_name"));
                String phone = cursor.getString(cursor.getColumnIndex("data1"));
                mDeleteMap.put(name, phone);
                deleteCount++;
            }
        }
        cursor.close();

        for (Map.Entry<String, String> entry : mDeleteMap.entrySet()) {
            String name = entry.getKey();
            String phone = entry.getValue();
            boolean delete = deletePhone(name, phone);
            LogManager.getInstance().logInfo("删除 " + name + " " + phone + " " + delete);
        }
    }

    public void processAccountContacts(String account, String contactsJson) {
        deletePhone(account);
        try {
            JSONObject jsonObject = new JSONObject(contactsJson);
            if (jsonObject.has(WxUiViewConfig.KEY_CONTACTS_PHONES)) {
                JSONArray phones = jsonObject.getJSONArray(WxUiViewConfig.KEY_CONTACTS_PHONES);
                for (int i = 0, len = phones.length(); i < len; i++) {
                    LogManager.getInstance().logInfo("phone = " + phones.get(i).toString());
                    JSONObject jo = phones.getJSONObject(i);
                    String name = "";
                    String phone = "";
                    if (jo.has("name")) {
                        name = jo.getString("name");
                    }
                    if (jo.has("number")) {
                        phone = jo.getString("number");
                    }
                    boolean inserted = insertContacts(account, name, phone);
                    LogManager.getInstance().logInfo("insert " + inserted + " name = " + name + " phone = " + phone);
                }
            }
        } catch (JSONException e) {
            e.printStackTrace();
            LogManager.getInstance().logError("解析错误 " + contactsJson);
        }
    }
}